package com.ruben;/**
 * @ClassName: FunctionDemo
 * @Date: 2020/11/9 0009 21:41
 * @Description:
 */

import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.SerializationUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
import com.ruben.pojo.User;
import com.ruben.utils.FunctionUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.util.function.Function;

/**
 * @ClassName: FunctionDemo
 * @Description: 我还没有写描述
 * @Date: 2020/11/9 0009 21:41
 * *
 * @author: <achao1441470436@gmail.com>
 * @version: 1.0
 * @since: JDK 1.8
 */
public class FunctionDemo {

    public FunctionUtils.IFunction function() {
        return new FunctionUtils.IFunction() {
            @Override
            public Object apply(Object ruben) {
                return ruben.getClass().getName();
            }
        };
    }

    public static void main(String[] args) {
        Function<User, User> identity = Function.identity();
        User user = identity.compose(obj -> {
            User tempUser = (User) obj;
            tempUser.setUsername("alex");
            return tempUser;
        }).andThen(obj -> {
            obj.setUsername("ruben");
            return obj;
        }).apply(new User("steve", "xxxxxx"));
        System.out.println(getAttributeName(User::getUsername));
        System.out.println(getUsername(User::getUsername, user));
        System.out.println(getNameLength(User::getUsername, user));
        System.out.println(getAchaoName(User::getUsername, user));
        FunctionUtils.IFunction<User, String> getUsername = User::getUsername;
        System.out.println(FunctionUtils.getAttributeName(getUsername));
    }

    public static String getAchaoName(Function<User, String> func, User user) {
        return func.compose(obj -> {
            User tempUser = (User) obj;
            tempUser.setUsername("achao");
            return tempUser;
        }).apply(user);
    }


    public static int getNameLength(Function<User, String> func, User user) {
        return func.andThen(String::length).apply(user);
    }

    public static String getUsername(Function<User, String> func, User user) {
        return func.apply(user);
    }

    /**
     * @MethodName: getAttributeName
     * @Description: 获取属性名
     * @Date: 2020/11/9 0009 22:13
     * *
     * @author: <achao1441470436@gmail.com>
     * @param: [func]
     * @returnValue: java.lang.String
     */
    public static String getAttributeName(SFunction<User, String> func) {
        SerializedLambda lambda = resolve(func);
        String methodName = lambda.getImplMethodName();
        return methodName.toLowerCase().substring(3);
    }

    public static SerializedLambda resolve(SFunction lambda) {
        try (ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(SerializationUtils.serialize(lambda))) {
            @Override
            protected Class<?> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
                Class<?> clazz = super.resolveClass(objectStreamClass);
                return clazz == java.lang.invoke.SerializedLambda.class ? SerializedLambda.class : clazz;
            }
        }) {
            return (SerializedLambda) objIn.readObject();
        } catch (ClassNotFoundException | IOException e) {
            throw ExceptionUtils.mpe("This is impossible to happen", e);
        }
    }

}
